package org.superheroes.androidserver.net.packets;

import android.util.Log;

public class RTPPacket
{
	private static final String LOG_TAG = RTPPacket.class.getName();
	
	private static int	HEADER_SIZE	= 12;

	private int			version;
	private int			padding;
	private int			extension;
	private int			cc;
	private int			marker;
	private int			payloadType;
	private int			sequenceNumber;
	private int			timeStamp;
	private int			ssrc;
	private int			payloadSize;

	private byte[]		header;
	private byte[]		payload;

	public RTPPacket( int pType, int frameNr, int time, byte[] data, int dataLength )
	{
		version = 2;
		padding = 0;
		extension = 0;
		cc = 0;
		marker = 0;
		ssrc = 0;

		sequenceNumber = frameNr;
		timeStamp = time;
		payloadType = pType;

		header = new byte[ HEADER_SIZE ];
		header[ 0 ] = ( byte ) ( version << 6 );
		header[ 0 ] = ( byte ) ( header[ 0 ] | padding << 5 );
		header[ 0 ] = ( byte ) ( header[ 0 ] | extension << 4 );
		header[ 0 ] = ( byte ) ( header[ 0 ] | cc );
		header[ 1 ] = ( byte ) ( header[ 1 ] | marker << 7 );
		header[ 1 ] = ( byte ) ( header[ 1 ] | pType );
		header[ 2 ] = ( ( byte ) ( sequenceNumber >> 8 ) );
		header[ 3 ] = ( ( byte ) ( sequenceNumber & 0xFF ) );
		header[ 4 ] = ( ( byte ) ( time >> 24 ) );
		header[ 5 ] = ( ( byte ) ( time >> 16 ) );
		header[ 6 ] = ( ( byte ) ( time >> 8 ) );
		header[ 7 ] = ( ( byte ) ( time & 0xFF ) );
		header[ 8 ] = ( ( byte ) ( ssrc >> 24 ) );
		header[ 9 ] = ( ( byte ) ( ssrc >> 16 ) );
		header[ 10 ] = ( ( byte ) ( ssrc >> 8 ) );
		header[ 11 ] = ( ( byte ) ( ssrc & 0xFF ) );

		payloadSize = dataLength;
		payload = new byte[ dataLength ];
		for ( int i = 0; i < dataLength; i++ )
		{
			payload[ i ] = data[ i ];
		}
	}

	public RTPPacket( byte[] packet, int length )
	{
		version = 2;
		padding = 0;
		extension = 0;
		cc = 0;
		marker = 0;
		ssrc = 0;

		if ( length >= HEADER_SIZE )
		{
			header = new byte[ HEADER_SIZE ];
			for ( int i = 0; i < HEADER_SIZE; i++ )
			{
				header[ i ] = packet[ i ];
			}

			payloadSize = length - HEADER_SIZE;
			payload = new byte[ payloadSize ];
			for ( int i = HEADER_SIZE; i < length; i++ )
			{
				payload[ i - HEADER_SIZE ] = packet[ i ];
			}

			payloadType = header[ 1 ] & 127;
			sequenceNumber = unsigned_int( header[ 3 ] ) + 256 * unsigned_int( header[ 2 ] );
			timeStamp = unsigned_int( header[ 7 ] ) + 256 * unsigned_int( header[ 6 ] ) + 65536 * unsigned_int( header[ 5 ] ) + 16777216 * unsigned_int( header[ 4 ] );
		}
	}

	public int getSequenceNumber()
	{
		return sequenceNumber;
	}

	public int getTimeStamp()
	{
		return timeStamp;
	}

	public int getPayloadType()
	{
		return payloadType;
	}

	public int getVersion()
	{
		return version;
	}

	public int getPadding()
	{
		return padding;
	}

	public int getExtension()
	{
		return extension;
	}

	public int getCC()
	{
		return cc;
	}

	public int getMarker()
	{
		return marker;
	}

	public int getSSRC()
	{
		return ssrc;
	}

	public void printHeader()
	{
		String headerString = "";
		
		for ( int i = 0; i < ( HEADER_SIZE - 4 ); i++ )
		{
			for ( int j = 7; j >= 0; j-- )
			{
				if ( ( ( 1 << j ) & header[ i ] ) != 0 )
				{
					headerString += 1;
				}
				else
				{
					headerString += 0;
				}
			}
			
			headerString += " ";
		}
		
		Log.i( LOG_TAG, headerString );
	}

	public int getPayloadLength()
	{
		return payloadSize;
	}

	public int getPayload( byte[] data )
	{
		for ( int i = 0; i < payloadSize; i++ )
		{
			data[ i ] = payload[ i ];
		}

		return payloadSize;
	}

	public int getLenght()
	{
		return payloadSize + HEADER_SIZE;
	}

	public int getPacket( byte[] packet )
	{
		for ( int i = 0; i < HEADER_SIZE; i++ )
		{
			packet[ i ] = header[ i ];
		}

		for ( int i = 0; i < payloadSize; i++ )
		{
			packet[ i + HEADER_SIZE ] = payload[ i ];
		}

		return payloadSize + HEADER_SIZE;
	}

	public static int unsigned_int( int nr )
	{
		if ( nr >= 0 )
		{
			return nr;
		}
		else
		{
			return 256 + nr;
		}
	}
}
